package com.qcc.cashier.pos;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;


import com.appinterface.update.AppJson;
import com.google.gson.Gson;
import com.landicorp.android.eptapi.DeviceService;
import com.landicorp.idcard.reader.lib.IDCardReader;
import com.landicorp.idcard.reader.lib.listener.IDCardReaderListener;
import com.landicorp.idcard.reader.lib.model.IDCardData;
import com.ums.AppHelper;
import com.appinterface.update.UpdateHelper;
import com.appinterface.update.UpdateListener;
import com.ums.anypay.service.IOnTransEndListener;
import com.ums.upos.sdk.exception.CallServiceException;
import com.ums.upos.sdk.exception.SdkException;
import com.ums.upos.sdk.printer.PrinterManager;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.Observer;
import android.provider.Settings;

public class PosHelper {

	private static String appId;
	private static String appKey;
	private static IDCardReader idCardReader;

	public static void setId(String appId) {
		PosHelper.appId = appId;
	}

	public static void setAppKey(String appKey) {
		PosHelper.appKey = appKey;
	}

	public static IDCardReader getCardReader() {
		return idCardReader;
	}

	private static void processTransResult(ObservableEmitter<String> emitter, String s) {
		HashMap<String, Object> hashMap = new Gson().fromJson(s, HashMap.class);
		if (hashMap.containsKey("transData")) {
			Map<String, Object> dataMap = (Map<String, Object>) hashMap.get("transData");
			if (dataMap.containsKey("resCode")) {
				String resCode = (String) dataMap.get("resCode");
				if ("00".equals(resCode)) {
					emitter.onNext(s);
					emitter.onComplete();
				} else {
					emitter.onError(new Throwable(s));
				}
			} else {
				emitter.onError(new Throwable(s));
			}
		} else {
			emitter.onError(new Throwable(s));
		}
	}

	public static Observable<String> pay(Activity context, double amount, String extOrderNo) {
		return Observable.create(emitter -> {
			String transAppName = "银行卡收款";
			String transAppId = "消费";
			JSONObject transData = new JSONObject();
			try {
				transData.put("amt", amount);// 交易金额输入整数时单位为分，输入小数时单位为元
				transData.put("appId", appId);// appId
				transData.put("extOrderNo", extOrderNo);
				// transData.put("isNeedPrintReceipt", true); // 是否打单true表示POS不打单
				// false或者不存在时表示由POS打单
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}

		});

	}

	/**
	 * 付款,合景多应用
	 *
	 * @param context
	 * @param amount
	 * @param extOrderNo
	 * @param name
	 * @param accountNo
	 * @return
	 */
	public static Observable<String> payHj(Activity context, boolean posT, double amount, String extOrderNo, String name, String accountNo, String merchantNo) {
		return Observable.create(emitter -> {
			String transAppName = "合景地产";
			String transAppId = posT ? "PosT缴费" : "缴费";
			JSONObject transData = new JSONObject();
			try {
				transData.put("amt", amount);// 交易金额输入整数时单位为分，输入小数时单位为元
				transData.put("appId", appId);// appId
				transData.put("extOrderNo", extOrderNo);
				//证件姓名
				transData.put("name", name);
				//结算账号
				transData.put("accountNo", accountNo);
				//商户订单号
				transData.put("merchantNo", merchantNo);
				//实名认证标识
				//0:表示直接进行银行卡交易
				//1:表示要先进行实名认证交易
				transData.put("certFlag", "0");
				// transData.put("isNeedPrintReceipt", true); // 是否打单true表示POS不打单
				// false或者不存在时表示由POS打单
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}catch (Error e) {
				e.printStackTrace();
				emitter.onError(e);
			}

		});

	}


	/**
	 * 付款,合景多应用
	 *
	 * @param context
	 * @param payJson
	 * @return
	 */
	public static Observable<String> payHjTest(Activity context, boolean posT, String payJson) {
		return Observable.create(emitter -> {
			String transAppName = "合景地产";
			String transAppId = posT ? "PosT缴费" : "缴费";
			JSONObject transData = new JSONObject(payJson);
			try {
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (Error e) {
				e.printStackTrace();
				emitter.onError(e);
			}

		});

	}

	public static Observable<String> payQRCode(Activity context, double amount, String extOrderNo) {
		return Observable.create(emitter -> {
			String transAppName = "POS 通";
			String transAppId = "扫一扫";
			JSONObject transData = new JSONObject();
			try {
				transData.put("amt", amount);// 交易金额输入整数时单位为分，输入小数时单位为元
				transData.put("appId", appId);// appId
				transData.put("extOrderNo", extOrderNo);
				// transData.put("isNeedPrintReceipt", true); // 是否打单true表示POS不打单
				// false或者不存在时表示由POS打单
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}

		});

	}

	/**
	 * 取消交易
	 *
	 * @param context
	 * @param orgTraceNo
	 * @return
	 */
	public static Observable<String> cancelOrder(Activity context, String orgTraceNo) {
		return Observable.create(emitter -> {
			String transAppName = "公共资源";
			String transAppId = "撤销";
			JSONObject transData = new JSONObject();
			try {
				transData.put("appId", appId);// appId
				transData.put("useScan", false);
				transData.put("orgTraceNo", orgTraceNo);
				// transData.put("isNeedPrintReceipt", true); // 是否打单true表示POS不打单
				// false或者不存在时表示由POS打单
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}
		});
	}

	/**
	 * 取消交易,合景多应用
	 *
	 * @param context
	 * @param orgTraceNo
	 * @return
	 */
	public static Observable<String> cancelOrderHj(Activity context, boolean posT, String orgTraceNo) {
		return Observable.create(emitter -> {
			String transAppName = "合景地产";
			String transAppId = posT ? "PosT撤销" : "撤销";
			JSONObject transData = new JSONObject();
			try {
				transData.put("appId", appId);// appId
				if (posT) {
					transData.put("useScan", false);
				}
//				transData.put("useScan", false);
				transData.put("orgTraceNo", orgTraceNo);
				// transData.put("isNeedPrintReceipt", true); // 是否打单true表示POS不打单
				// false或者不存在时表示由POS打单
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}catch (Error e) {
                e.printStackTrace();
                emitter.onError(e);
            }
		});
	}

	/**
	 * pos机打开设置界面
	 *
	 * @param context
	 * @return
	 */
	public static void settings(Activity context, int settingType) {
		Intent intent;
		switch (settingType) {
			case 1:
				intent = new Intent(Settings.ACTION_SETTINGS);
				break;
			default:
				intent = new Intent(Settings.ACTION_SETTINGS);
		}

		context.startActivity(intent);
	}

	/**
	 * 签到
	 *
	 * @param context
	 * @return
	 */
	public static Observable<String> sign(Activity context) {
		return Observable.create(emitter -> {
			String transAppName = "公共资源";
			String transAppId = "签到";
			JSONObject transData = new JSONObject();
			try {
				transData.put("appId", appId);// appId
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}catch (Error e) {
                e.printStackTrace();
                emitter.onError(e);
            }

		});

	}

	/**
	 * 结算
	 *
	 * @param context
	 * @return
	 */
	public static Observable<String> balance(Activity context) {
		return Observable.create(emitter -> {
			String transAppName = "公共资源";
			String transAppId = "换班";
			JSONObject transData = new JSONObject();
			try {
				transData.put("appId", appId);// appId
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}catch (Error e) {
                e.printStackTrace();
                emitter.onError(e);
            }

		});

	}

	/**
	 * 余额查询
	 *
	 * @param context
	 * @return
	 */
	public static Observable<String> balanceYe(Activity context) {
		return Observable.create(emitter -> {
			String transAppName = "公共资源";
			String transAppId = "余额查询";
			JSONObject transData = new JSONObject();
			try {
				transData.put("appId", appId);// appId
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (Error e) {
				e.printStackTrace();
				emitter.onError(e);
			}

		});

	}

	/**
	 * 签到
	 *
	 * @param context
	 * @return
	 */
	public static Observable<String> callTrans(Activity context,String transAppName,String transAppId,String transDataJson) {
		return Observable.create(emitter -> {//
			JSONObject transData = new JSONObject(transDataJson);
			try {
				transData.put("appId", appId);// appId
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}catch (Error e) {
                e.printStackTrace();
                emitter.onError(e);
            }

		});

	}

	private static void initCardReader(Activity context) {
		if (idCardReader == null) {
			// 0内置，1外置，-1未设置（默认-1 如果设备名含有C10为外置，不含则内置）
			idCardReader = new IDCardReader(context, -1);
			idCardReader.setLogflag(0);// 是否开启亿数日志（默认不开启）
			idCardReader.setIsBeepSucc(0);// 0寻卡蜂鸣 1读卡成功蜂鸣 -1不启用蜂鸣（默认0）
			idCardReader.setIsAutoBindDevice(1);// 是否自动绑定设备服务0-用户自行绑定 1-自动绑定（默认1）
		}
	}

	public static Observable<Boolean> setupCardReader(Activity context, String loginAddress, String md5Key) {
		return Observable.create(emitter -> {
			try {
				initCardReader(context);
				DeviceService.login(context);
				if (idCardReader != null) {
					idCardReader.setLoginAddress(loginAddress);
					idCardReader.setMD5Key(md5Key);
					emitter.onNext(true);
					emitter.onComplete();
				} else {
					emitter.onError(new Throwable("cardReader is null"));
				}
			} catch (Error e) {
				emitter.onError(e);
			}
		});
	}

	/**
	 * 读取身份证卡信息
	 *
	 * @return
	 */
	public static Observable<IdentifyInfoBean> readCardInfo(Activity context) {
		return Observable.create(emitter -> {
			try {
				initCardReader(context);
				idCardReader.ReadIDCard(new IDCardReaderListener() {
					@Override
					public void onProgress(String resCode, String resMsg) {
						IdentifyInfoBean infoBean = new IdentifyInfoBean();
						infoBean.setStart(true);
						infoBean.setResMsg(resMsg);
						emitter.onNext(infoBean);
					}

					@Override
					public void onFail(String resCode, String resMsg) {
						IdentifyInfoBean infoBean = new IdentifyInfoBean();
						infoBean.setResMsg(resMsg);
						infoBean.setError(true);
						emitter.onNext(infoBean);
					}

					@Override
					public void onSuccess(IDCardData idCardData) {
						idCardReader.stopReadIDCard();
						IdentifyInfoBean infoBean = new IdentifyInfoBean();
						infoBean.setComplete(true);
						infoBean.setBean(idCardData);
						emitter.onNext(infoBean);
						emitter.onComplete();
					}
				}, true);
			} catch (Error e) {
				emitter.onError(e);
			}
		});
	}

	/**
	 * 停止读卡
	 */
	public static void stopReadCard() {
		if (idCardReader != null) {
			idCardReader.stopReadIDCard();
		}
	}

	/*
	 * 获取设备信息
	 *
	 * @param context
	 *
	 * @return
	 */
	public static String getPosInfo(Activity context) {
		return AppHelper.getBaseSysInfo(context);
	}

	/**
	 * 打印
	 */
	public static String posPrint(Activity context, String imgPath) {
		try {
			return AppHelper.callSyncPrint(context, imgPath);
		} catch (Exception e) {
			return e.getMessage() + e.getStackTrace();
		}
	}

	/**
	 * 打印文本
	 */
	public static String posPrintText(String text) {
		try {
			PrinterManager printerManager = new PrinterManager();
			try {
				printerManager.initPrinter();
				int res = printerManager.setPrnScript(text, "1");
				return res + "";
			} catch (SdkException e) {
				e.printStackTrace();
				return e.getMessage() + e.getStackTrace();
			} catch (CallServiceException e) {
				e.printStackTrace();
				return e.getMessage() + e.getStackTrace();
			}
		} catch (Error e) {
			e.printStackTrace();
			return e.getMessage() + e.getStackTrace();
		}
	}

	/**
	 * pos机根据traceNo打印pos小票
	 *
	 * @param context
	 * @param orgTraceNo
	 * @return
	 */
	public static Observable<String> rePrint(Activity context, String orgTraceNo) {
		return Observable.create(emitter -> {
			String transAppName = "公共资源";
			String transAppId = "交易明细";
			JSONObject transData = new JSONObject();
			try {
				transData.put("appId", appId);// appId
				transData.put("traceNo", orgTraceNo); // 若为000000，则重打印最后一笔交易信息，且为联机查询）；（extOrderNo与traceNo至少一个非空，若两个参数都不为空，则以这两个参数为查询条件进行联合查询）
				// transData.put("isNeedPrintReceipt", true); // 是否打单true表示POS不打单
				// false或者不存在时表示由POS打单
				// transData.put("isShowDetailPage", true); //
				// 当该值为true时，表示调起交易明细页面，当该值为false或者不存在时表示为重打
				AppHelper.callTrans(context, transAppName, transAppId, transData, new IOnTransEndListener() {
					@Override
					public void onEnd(String s) {
						processTransResult(emitter, s);
					}
				});
			} catch (JSONException e) {
				e.printStackTrace();
				emitter.onError(e);
			}catch (Error e) {
                e.printStackTrace();
                emitter.onError(e);
            }

		});

	}
	/**
	 * 自更新
	 */
	public static Observable<String> autoSelfUpdate(Activity context) {
		return Observable.create(emitter -> {
			try{
				String tag = "updateSelfService";
				new Thread(new Runnable() {
					@Override
					public void run() {
						String appkey = appKey;
						String pkgName = "com.qcc.cashier";
						Boolean isAutoInstall = true;
						Boolean checkNetType = true;
						/**检查更新并下载新的apk
						 * param String appkey 开放应用申请而来的appkey用来校验当前应用是否有下载apk的权限
						 * param String packName 当前应用的包名
						 * param Boolean isAutoInstall 下载完成后是否自动安装，true自动安装，false不自动安装
						 * param Boolean checkNetType 下载前是否忽略当前是移动网络还是WiFi
						 * param com.appinterface.update.UpdateListener 监听器监听下载和安装的状态*/
						UpdateHelper.download(context, appkey, pkgName, isAutoInstall, checkNetType, new UpdateListener() {
							@Override
							public void onCheckUpdateResult(int i, AppJson appJson) {
								super.onCheckUpdateResult(i, appJson);
								Log.d(tag, "--retCode--" + i + "\n--result--" + appJson);
								emitter.onNext(i==1?"有更新":"无更新");
								switch (i){
									case  1:
										emitter.onNext(i==1?"有更新":"无更新");
										break;
									case 2:
										emitter.onNext(i==1?"有更新":"无更新");
										emitter.onComplete();
										break;
								}
								/**
								 * i表示检查更新结果：
								 * 1：有更新；2：无更新*/
							}

							@Override
							public void onProgress(int i) {
								super.onProgress(i);
								Log.d(tag, "--progress-- " + i);
								emitter.onNext(i+"");
							}

							@Override
							public void onStateChanged(int i) {
								super.onStateChanged(i);
								Log.d(tag, "--onStateChanged-- " + i);
								String[] info={"等待下载","正在下载","正在暂停下载","下载已暂停","下载完成","下载失败","正在取消下载","下载已取消","正在安装","等待安装","安装完成","安装失败","安装失败","后台无此应用"};
								switch (i){
									case  1:
									case  2:
									case  3:
									case  4:
									case  5:
									case  7:
									case  9:
									case  10:
										emitter.onNext(info[i-1]);
										break;
									case 8:
									case 12:
									case 14:
										emitter.onNext(info[i-1]);
										break;
									case 11:
										emitter.onNext(info[i-1]);
										emitter.onComplete();
										break;
								}
								/**i表示下载或安装的状态，对应释义：
								 * 1：等待下载
								 * 2：正在下载
								 * 3：正在暂停下载
								 * 4：下载已暂停
								 * 5：下载完成
								 * 6：下载失败
								 * 7：正在取消下载
								 * 8：下载已取消
								 * 9：正在安装
								 * 10：等待安装
								 * 11：安装完成
								 * 12：安装失败
								 * 13：安装已取消
								 * 14：后台无此应用*/
							}
						});
					}
				}).start();
//				emitter.onComplete();
			}catch (Error e){
				e.printStackTrace();
				emitter.onError(e);
			}

		});
	}
}
